home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug187 / strings.c < prev    next >
C/C++ Source or Header  |  1985-12-30  |  11KB  |  302 lines

  1. /*@*****************************************************/
  2. /*@                                                    */
  3. /*@ strings is a package of string functions used      */
  4. /*@        to process command tails.  I have not       */
  5. /*@        used them and they do not compile on        */
  6. /*@        DeSmet C.  They looked useful, so I have    */
  7. /*@        saved them.                                 */
  8. /*@                                                    */
  9. /*@*****************************************************/
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. /*
  14. ;;      file:   _STRING.C
  15. ;;
  16. ;; --------------- Command Tail Processing Functions ---------------
  17. ;;
  18. ;;      This next set of functions are meant to be used together. Examples
  19. ;;on their use follows.
  20. ;;
  21. ;;
  22. ;;int num_args(string)  Returns the number of args in the string, seperated
  23. ;;                      by delims (see delim(), below). Leading delimiters
  24. ;;                      are ignored.
  25. ;;
  26. ;;char *next_arg(string)        Returns a pointer to the next arg, delimited
  27. ;;                      by a delim, skipping over the current arg. Use via
  28. ;;                      ptr= nextarg(ptr) to skip to each argument. All
  29. ;;                      switches at the end of the current arg are skipped.
  30. ;;
  31. ;;
  32. ;;char *skip_delim(string) Skips leading delims in a string. returns a pointer.
  33. ;;
  34. ;;cpyarg(to,from)               Copies a string, up to the next delim or switch.
  35. ;;                      Leading and trailing delimiters are stripped (from
  36. ;;                      the output string) and a null terminator is added.
  37. ;;
  38. ;;                      after cpyarg()          FROM: foo/b
  39. ;;                                              TO: foo
  40. ;;
  41. ;;delim(c)              Returns true if the character is a delimiter.
  42. ;;                      Nulls are not considered a delimiter. The list of
  43. ;;                      delimiters is contained in the array '_dlmlst', and
  44. ;;                      can be changed via newdelim().
  45. ;;
  46. ;;newdelim(s)           Replace the list of delimiters. The string 's' must
  47. ;;                      be less than 20 chars.
  48. ;;
  49. ;;isswitch(c)           Returns true if the character is the current DOS
  50. ;;                      switch character.
  51. ;;
  52. ;;char filtchar(c)      Convert a character to one legal for an MSDOS filename.
  53. ;;                      Illegal characters such as switch or path seperators,
  54. ;;                      control characters, etc are changed to '$'. Bit 7 is
  55. ;;                      masked off. (Disallows foreign language support??)
  56. ;;
  57. ;;wild(string)          Returns true if the string contains a star or question.
  58. ;;
  59. ;;char *strip_path(out,in) Copies the disk specifier or pathname to the output
  60. ;;                      array, and returns a pointer to the name in the input
  61. ;;                      string. Drive specs are considered a path, and are
  62. ;;                      treated as such by DOS. Stripping "a:foo" and
  63. ;;                      "bin/foo/framis.asm" result in:
  64. ;;
  65. ;;                              IN:     "A:"
  66. ;;                              IN:     "bin\foo"
  67. ;;
  68. ;;                              OUT:    "A:"
  69. ;;                              OUT:    "bin\"
  70. ;;
  71. ;;strip_switch(out,in)  Copy the switches from the in string, remove the switch
  72. ;;                      character and put all the characters in the out array.
  73. ;;                      Each is converted to upper case, and the string is null
  74. ;;                      terminated.
  75. ;;
  76. ;;ispath_delim(c)       Returns true if the character is a legal pathname
  77. ;;char c;               component seperator. The only two characters legal
  78. ;;                      (here at least) are \ and-or /. For example:
  79. ;;
  80. ;;                      Switch character = /
  81. ;;                              ispath_delim('/') == 0
  82. ;;                              ispath_delim('\\') == 1
  83. ;;                      Switch character = -
  84. ;;                              ispath_delim('/') == 1
  85. ;;                              ispath_delim('\\') == 1
  86. ;;                      Switch character = \
  87. ;;                              ispath_delim('/') == 1
  88. ;;                              ispath_delim('\\') == 0
  89. ;;
  90. ;;
  91. ;; --------- Command Tail Processing Examples ----------
  92. ;;
  93. ;;      This is an example of one way to use the above functions to process
  94. ;;an MSDOS program command tail. You do not need to know what the system switch
  95. ;;character or legal path seperators are. If you can't handle paths, strip them
  96. ;;off. Assume there is a pointer, p, that points to a command tail string:
  97. ;;
  98. ;;      p= "  source.ext abc.asm/v+\bin\def.com /x/y/z"
  99. ;;
  100. ;;      p= skip_delim(p);               /* p= "source.exe abc...... */
  101. ;;
  102. ;;      p= next_arg(p);                 /* p= "abc.asm/v.... "  */
  103. ;;      cpyarg(work,p);                 /* work= "abc.asm"  */
  104. ;;      s= strip_path(work,p));         /* s= "abc.asm"   path= ""  */
  105. ;;      strip_switch(sw,p);             /* sw= "V"  */
  106. ;;
  107. ;;      p= next_arg(p);                 /* p= "\bin\def.com"  */
  108. ;;      cpyarg(work,p);                 /* work= "\bin\def.com"  */
  109. ;;      s= strip_path(path,p);          /* s= "def.com"  path= "\bin\"  */
  110. ;;      strip_switch(sw,p);             /* sw= ""  */
  111. ;;
  112. ;;      p= next_arg(p);                 /* p= "/x/y/z"  */
  113. ;;      cpyarg(work,p);                 /* work= ""  */
  114. ;;      s= strip_path(path,p);          /* s= ""  path= ""  */
  115. ;;      strip_switch(sw,p);             /* sw= "XYZ"  */
  116. ;;
  117. ;;      p= next_arg(p);                 /* p= ""  */
  118. ;;
  119. ;;      while (num_args(p)              /* while not end of string ... */
  120. ;;      while (*p)                      /* another way ... */
  121. ;;
  122. ;;
  123. ;;char *name,sw[4],path[40];
  124. ;;
  125. ;;      p= skip_delim(p);
  126. ;;      while (num_args(p) > 0) {       /* *p points to the current arg, */
  127. ;;              name= strip_path(path,p);
  128. ;;              strip_switch(sw,p);
  129. ;;              printf("Path= %s, Name= %s, Switches= %s\n",path,name,sw);
  130. ;;      }
  131. ;;
  132. */
  133. /* Return the number of args left in the string. */
  134.  
  135. num_args(string)
  136. char *string;
  137. {
  138. int count;
  139.  
  140.         count= 0;
  141.         string= (char *)skip_delim(string);     /* skip leading blanks, */
  142.         while (*string) {
  143.                 ++count;                        /* count one, */
  144.                 string= (char *)next_arg(string); /* find next, */
  145.         }
  146.         return(count);
  147. }
  148. /* Return a pointer to the next argument in the string. */
  149.  
  150. next_arg(string)
  151. char *string;
  152. {
  153.         while ((!delim(*string)) && *string)            /* skip this one, */
  154.                 ++string;                               /* up to delim, */
  155.         string= (char *)skip_delim(string);             /* then skip delims, */
  156.         return(string);
  157. }
  158.  
  159. /* Skip over the leading delimiters in a string. */
  160.  
  161. skip_delim(string)
  162. char *string;
  163. {
  164.         while (delim(*string) && *string)
  165.                 ++string;
  166.         return(string);
  167. }
  168. /* Copy the string to the destination array, stopping if we find one
  169. of our delimiters or switches. */
  170.  
  171. cpyarg(to,from)
  172. char *to;
  173. char *from;
  174. {
  175.         while ( (!delim(*from)) && (!isswitch(*from)) && *from)
  176.                 *to++= *from++;
  177.         *to= '\0';
  178.         return;
  179. }
  180. /* Strip any switches from the input string, put into the output array. */
  181.  
  182. strip_switch(out,in)
  183. char *out;
  184. char *in;
  185. {
  186.         while (*in && (!isswitch(*in)))         /* skip to end of string */
  187.                 ++in;                           /* or first switch, */
  188.  
  189.         while (*in && isswitch(*in)) {          /* copy switch args while */
  190.                 ++in;
  191.                 *out++ = toupper(*in);          /* stripping switch chars, */
  192.                 ++in;
  193.         }
  194.         *out= '\0';                             /* terminate it, */
  195.         return;
  196. }
  197. /* ----- List of legal delimiters. This is the default list ----- */
  198.  
  199. char _dlmlst[20] = { " \t,+" }; /* space, tab, comma, plus */
  200.  
  201. /* Change the list of delimiters. */
  202.  
  203. newdelim(s)
  204. char *s;
  205. {
  206.         strcpy(_dlmlst,s);
  207.         return;
  208. }
  209.  
  210. /* Return true if the character is a delimiter from the list above. */
  211.  
  212. delim(c)
  213. char c;
  214. {
  215. int i;
  216.         for (i= 0; _dlmlst[i]; ++i) {
  217.                 if (c == _dlmlst[i]) return(1);
  218.         }
  219.         return(0);
  220. }
  221. /* return true if the character is the current switch character. */
  222.  
  223. isswitch(c)
  224. char c;
  225. {
  226.         return(c == _charop(0,0));
  227. }
  228. /* Clean up the character for a legal MSDOS filename. Convert undesireable
  229. characters to a dollar. */
  230.  
  231. char filtchar(c)
  232. char c;
  233. {
  234.         c&= 0x7f;                       /* strip bit 7, */
  235.         if (isswitch(c) || ispath_delim(c) || (c < ' ') || (c > '~') )
  236.                 c= '$';                 /* dont allow illegal chars */
  237.         c= toupper(c);                  /* all uppercase, */
  238.         return(c);
  239. }
  240. /* Return 1 if the string is a wild filespec. */
  241.  
  242. wild(string)
  243. char *string;
  244. {
  245. char *p;
  246.  
  247.         p= string;
  248.         while (*p) {
  249.                 if (*p == '?')
  250.                         return(1);
  251.                 if (*p == '*')
  252.                         return(1);
  253.                 ++p;
  254.         }
  255.         return(0);                              /* not wild. */
  256. }
  257. /* Strip the pathname or disk specifier from a filename, return it in a
  258. seperate array. We do this by initially copying the entire name in, then
  259. searching for the colon or slash. Right after the last one we find,
  260. stuff a null, removing the name part.
  261.  
  262. Also return a pointer to the name part in the input name. */
  263.  
  264. strip_path(out,in)
  265. char *out;
  266. char *in;
  267. {
  268. char *name;
  269. char *endpath;
  270.  
  271.         strcpy(out,in);                 /* duplicate, for working, */
  272.         name= in;                       /* point to name, */
  273.         endpath= out;                   /* and end of path part, */
  274.  
  275.         while (*in) {                   /* look for slashes or colons, */
  276.                 if (*in == ':') {       /* if a colon, */
  277.                         endpath= ++out; /* point to name, */
  278.                         name= ++in;
  279.                 } else if (ispath_delim(*in)) {
  280.                         endpath= ++out; /* move the pointer up, */
  281.                         name= ++in;
  282.                 } else {
  283.                         ++in;
  284.                         ++out;
  285.                 }
  286.         }
  287.         *endpath= '\0';                 /* delete the name part, */
  288.         return(name);                   /* return ptr to name part. */
  289. }
  290.  
  291. /* Return true if the character is a legal path name component seperator.
  292. The legal ones here are \ or /, depending on what the switch character is. */
  293.  
  294. ispath_delim(c)
  295. char c;
  296. {
  297.         if ((c == '\\') && (!isswitch('\\'))) return(1);
  298.         if ((c == '/') && (!isswitch('/'))) return(1);
  299.         return(0);
  300. }
  301.  
  302.